<?php

namespace app\webactive\service;

use app\common\cachemodel\User;
use app\common\cachemodel\UserCoupon;
use app\common\cachemodel\wecaht\WechatBlessRecord;
use app\common\cachemodel\wecaht\WechatLingqianChangeCouponRecord;
use app\common\cachemodel\wecaht\WechatLingqianCompleteRecord;
use app\common\cachemodel\wecaht\WechatLingqianUserCards;
use app\common\cachemodel\wecaht\WechatLingqianUserCardsChangeRecode;
use app\common\cachemodel\wecaht\WechatUser;
use app\common\cachemodel\ZlCouponAttr;
use app\common\lib\IAuth;
use app\common\lib\Util;
use think\Config;
use think\Log;

/**
 * 灵签与祈福
 */
class LingqianAndBless
{
    /**
     * 登录
     * @param array $wechatInfo 微信 用户信息
     * @return array
     */
    public function Login(array $wechatInfo)
    {
        // $wechatInfo = [
        //     'openid' => '',
        //     'unionid' => '',
        //     'headimgurl' => '',
        //     'nickname' => '',
        //     'sex' => '',
        // ];
        $userInfo = [
            'openid' => $wechatInfo['openid'] ?? '',
            'unionid' => $wechatInfo['unionid'] ?? '',
            'headimgurl' => $wechatInfo['headimgurl'] ?? '',
            'nickname' => $wechatInfo['nickname'] ?? '',
            'sex' => $wechatInfo['sex'] ?? 0,   // 1男 2女 0未知
        ];
        $nowTime = time();
        if (empty($userInfo['unionid']))
        {
            return [
                'success' => false,
                'msg' => '服务异常，微信信息缺失～',
            ];
        }
        $tokenData = [
            'access_token' => IAuth::setAppLoginToken('wechat:' . $userInfo['unionid']),
            'token_expires' => strtotime('+30 days'),
        ];
        try
        {
            $wechatUserModel = new WechatUser();
            $userData = $wechatUserModel->where(['unionid' => $userInfo['unionid']])->order('id desc')->find();
            if ($userData)
            {   // 登录
                $wechatUserModel->UpdateData($userData['id'], $tokenData);
                $id = (int)$userData['id'];
            } else
            {   // 注册
                if ($userInfo['headimgurl'])
                {
                    $avatarInfo = Util::wxImgUploadOss($userInfo['headimgurl'], 'uploads/avatar');
                    if (false === $avatarInfo['success'])
                    {
                        Log::write('微信登录  上传三方头像失败，' . $avatarInfo['message'], 'error');
                    }
                }
                $data = [
                    'access_token' => $tokenData['access_token'],
                    'token_expires' => $tokenData['token_expires'],
                    'openid' => $userInfo['openid'],
                    'unionid' => $userInfo['unionid'],
                    'nickname' => $userInfo['nickname'],
                    'headimgurl' => $userInfo['headimgurl'],
                    'sex' => $userInfo['sex'],
                    'create_time' => $nowTime,
                    'last_login_time' => $nowTime,
                ];
                $id = $wechatUserModel->insertGetId($data);
                $id = (int)$id;
            }

            return [
                'success' => true,
                'access_token' => $tokenData['access_token'],
                'id' => $id,
            ];
        }
        catch (\Exception $e)
        {
            \think\Log::write(__CLASS__ . ' => ' . __FUNCTION__ . '()异常：' . $e->getMessage() . '失败信息：' . $e->getFile() . ':' . $e->getLine(), 'error', true);
            return [
                'success' => false,
                'msg' => '服务异常，登录失败～',
            ];
        }
    }

    /**
     * ---  祈福  ---
     * 获取 祈福 首页
     * @param int $uid
     * @return array
     * @throws \Exception
     */
    public function getBlessHome(int $uid)
    {
        $blessInfo = (new WechatBlessRecord())->getBlessInfo($uid);

        return [
            [
                'type' => 1, // 1=>财富 2=>爱情 3=>好事
                'status' => $blessInfo['bless1'] ?? 0,
            ], [
                'type' => 2,
                'status' => $blessInfo['bless2'] ?? 0,
            ], [
                'type' => 3,
                'status' => $blessInfo['bless3'] ?? 0,
            ],
        ];
    }

    /**
     * ---  祈福  ---
     * 获取 祈福 详情
     * @param int $uid
     * @param int $type 1=>财富 2=>爱情 3=>好事
     * @return array
     * @throws \Exception
     */
    public function getBlessDetail(int $uid, int $type)
    {
        $wechatBlessRecordModel = new WechatBlessRecord();
        $blessInfo = $wechatBlessRecordModel->getBlessInfo($uid);

        switch ($type)
        {
            case 1:
                $key = 'bless1';
                $timeKey = 'bless1_time';
                break;
            case 2:
                $key = 'bless2';
                $timeKey = 'bless2_time';
                break;
            case 3:
                $key = 'bless3';
                $timeKey = 'bless3_time';
                break;
            default:
                return [
                    'success' => false,
                    'msg' => '服务异常，祈福类型不存在～',
                ];
        }

        return [
            $key => $blessInfo[$key],
            $timeKey => $blessInfo[$timeKey],
        ];
    }

    /**
     * ---  祈福  ---
     * 开始 上香 祈福
     * @param int $uid
     * @param int $type 1 =>财富 2=>爱情 3=>好事
     * @return array
     * @throws \Exception
     */
    public function startBless(int $uid, int $type)
    {
        $wechatBlessRecordModel = new WechatBlessRecord();
        $blessInfo = $wechatBlessRecordModel->getBlessInfo($uid);

        $nowTime = time();
        switch ($type)
        {
            case 1:
                $key = 'bless1';
                $timeKey = 'bless1_time';
                break;
            case 2:
                $key = 'bless2';
                $timeKey = 'bless2_time';
                break;
            case 3:
                $key = 'bless3';
                $timeKey = 'bless3_time';
                break;
            default:
                return [
                    'success' => false,
                    'msg' => '服务异常，祈福类型不存在～',
                ];
        }

        if ($blessInfo[$key] === 1)
        {
            return [
                'success' => true,
            ];
        }

        if ($blessInfo['id'])
        {   // 更新
            $data = [
                $key => 1,
                $timeKey => $nowTime,
            ];
            $wechatBlessRecordModel->UpdateData($blessInfo['id'], $uid, $blessInfo['date'], $data);
        } else
        {   // 新增
            $data = [
                'uid' => $uid,
                'date' => (int)(date('Ymd', $nowTime)),
                $key => 1,
                $timeKey => $nowTime,
                'create_time' => $nowTime,
            ];

            $wechatBlessRecordModel->SaveData($data);
        }

        return [
            'success' => true,
        ];
    }

    /**
     * ---  灵签  ---
     *  获取 今日 抽牌信息
     * @param int $uid
     * @return array
     * @throws \Exception
     */
    public function getTodayDrawCardInfo(int $uid)
    {
        $date = (int)(date('Ymd'));
        $info = (new WechatLingqianUserCardsChangeRecode())->getTodayDrawCardData($uid, $date);

        if ($info)
        {
            return [
                'is_draw' => 1, // 今天是否 抽牌
                'card_id' => $info['card_id'],  // 抽的牌 ID
            ];
        } else
        {
            return [
                'is_draw' => 0,
                'card_id' => 0,
            ];
        }
    }

    /**
     * ---  灵签  ---
     * 开始 抽牌
     * @param int $uid
     * @return array
     * @throws \Exception
     */
    public function startDraw(int $uid)
    {
        $date = (int)(date('Ymd'));
        $info = (new WechatLingqianUserCardsChangeRecode())->getTodayDrawCardData($uid, $date);
        if ($info)
        {
            return [
                'success' => true,
                'card_id' => $info['card_id'],  // 抽的牌 ID
            ];
        }
        // 获取用户的卡牌信息
        $wechatLingqianUserCardsModel = new WechatLingqianUserCards();
        $userCardList = $wechatLingqianUserCardsModel->getUserCardsInfo($uid);
        // 抽牌逻辑
        // ---------------------------------------------
        /**
         * 1、 本月 已中奖用户 不再中奖
         * 2、 已经有女王卡 不再抽中 女王卡
         * 3、 女王卡 每月上限 10张
         * 4、 普通卡 每月凑齐上限 3张
         * 5、 普通卡 前48张随机出不重复的
         * 6、 普通卡 已凑齐时 再次抽卡 至少保留一张卡牌 数量只有 1
         */
        $cardId = 0;
        // 获取本月中奖用户信息
        $wechatLingqianCompleteRecordModel = new WechatLingqianCompleteRecord();
        $curMonthCompleteRecord = $wechatLingqianCompleteRecordModel->getCompleteData();
        $curMonthCompleteUids = array_merge($curMonthCompleteRecord[1]['uids'], $curMonthCompleteRecord[2]['uids']);
        // 能否中奖 本月已中奖用户 不再抽奖
        $isWinAuth = !in_array($uid, $curMonthCompleteUids);
        if ($isWinAuth && $curMonthCompleteRecord[1]['num'] < 10 && (!isset($userCardList[1]) || $userCardList[1]['num'] === 0)) // 已经有女王卡 不在具备抽女王卡的资格
        {   // 有机会抽中 女王卡  且 本月发放女王卡数量小于10 且 身上没有女王卡
            $i = mt_rand(1, 5000); // 中奖概率 5000 分之一
            if ($i === 1)
            {   // 已中奖
                $cardId = 1;
            }
        }
        if ($cardId !== 1)
        {   // 未 中奖女王卡
            unset($userCardList[1]);
            $cardNum = 0;
            $hasCards = []; // 拥有的卡片
            $noCards = [];  // 没有的卡牌
            $num1Cards = [];
            for ($i = 2; $i <= 51; $i++)
            {
                if (isset($userCardList[$i]) && $userCardList[$i]['num'] > 0)
                {   // 拥有的卡牌
                    $hasCards[] = $i;
                    $cardNum++;
                    if ($userCardList[$i]['num'] === 1)
                    {
                        $num1Cards[] = $i;
                    }
                } else
                {   // 没有的卡牌
                    $noCards[] = $i;
                }
            }
            if ($cardNum < 48)
            {   // 前48张随机出不重复的
                shuffle($noCards);
                $cardId = array_pop($noCards);
            } elseif ($cardNum === 48)
            {   // 10% 的概率 出不同的卡牌
                if (mt_rand(1, 10) === 1)
                {   // 10%的概率中奖 抽中 不同的卡
                    shuffle($noCards);
                    $cardId = array_pop($noCards);
                } else
                {   // 没有抽中 不同的卡
                    shuffle($hasCards);
                    $cardId = array_pop($hasCards);
                }
            } else
            {   // 今日 有中奖资格 10%的概率中奖
                $dayNum = max(3 - $curMonthCompleteRecord[2]['num'], 0);
                $winDays = $wechatLingqianCompleteRecordModel->getCompleteWinDate($dayNum);
                $day = (int)date('d');
                $todayWinAuth = $isWinAuth && in_array($day, $winDays, true); // 今天是否 有中奖 资格
                if ($todayWinAuth && mt_rand(1, 10) === 1)
                {   // 有中奖资格 并且 10%的概率中奖
                    $cardId = current($noCards);
                } else
                {
                    if (count($num1Cards) !== 1)
                    {
                        shuffle($hasCards);
                        $cardId = array_pop($hasCards);
                    } else
                    {
                        $num1CardId = $num1Cards[0];
                        $hasCards = array_filter($hasCards, function ($value) use ($num1CardId)
                        {
                            return $value != $num1CardId;
                        });
                        shuffle($hasCards);
                        $cardId = array_pop($hasCards);
                    }
                }
            }
        }

        if (isset($userCardList[$cardId]))
        {
            $changeData[] = [
                'id' => $userCardList[$cardId]['id'],
                'card_id' => $userCardList[$cardId]['card_id'],
                'num' => $userCardList[$cardId]['num'] + 1,
                'change_num' => 1,
            ];
        } else
        {
            $changeData[] = [
                'card_id' => $cardId,
                'num' => 1,
                'change_num' => 1,
            ];
        }
        $res = $wechatLingqianUserCardsModel->userChangeCardsInfo($uid, $changeData, 1);
        if ($res)
        {
            return [
                'success' => true,
                'card_id' => $cardId,  // 抽的牌 ID
            ];
        } else
        {
            return [
                'success' => false,
                'msg' => '服务异常，请稍后再试～',
            ];
        }
    }

    /**
     * ---  灵签  ---
     * 获取卡牌详情
     * @param int $cardId
     * @return array
     */
    public function getCardDetail(int $cardId)
    {
        $cardConfig = Config::load(APP_PATH . 'webactive/extra/lingqian.php', 'lingqian', 'webactive');
        if ($cardId === 1)
        {
            return [
                'success' => true,
                'data' => $cardConfig['goddess_card'],
            ];
        } else
        {
            if (isset($cardConfig['card_list'][$cardId]))
            {
                return [
                    'success' => true,
                    'data' => $cardConfig['card_list'][$cardId],
                ];
            } else
            {
                return [
                    'success' => false,
                    'msg' => '服务异常，未知的卡',
                ];
            }
        }
    }

    /**
     * ---  灵签  ---
     * 我的牌组
     * @param int $uid
     * @return array
     */
    public function getMyCardList(int $uid)
    {
        // 获取用户的卡牌信息
        $wechatLingqianUserCardsModel = new WechatLingqianUserCards();
        $userCardList = $wechatLingqianUserCardsModel->getUserCardsInfo($uid);

        $cardConfig = Config::load(APP_PATH . 'webactive/extra/lingqian.php', 'lingqian', 'webactive');
        $resData = [];
        $goddessCard = $cardConfig['goddess_card'];
        $goddessCard['num'] = $userCardList[1]['num'] ?? 0;

        $resData[] = $goddessCard;
        foreach ($cardConfig['card_list'] as $cardId => $cardInfoItem)
        {
            $cardInfoItem['num'] = $userCardList[$cardId]['num'] ?? 0;
            $resData[] = $cardInfoItem;
        }

        return $resData;
    }

    /**
     * ---  灵签  ---
     * 卡牌兑换
     * @param int $uid
     * @param int $type 1=>女王卡兑换月运免费券 2=>50张不同的卡兑换年运免费券
     * @param string $uen 优惠券发放用户 准了号
     * @return array
     * @throws \Exception
     */
    public function cardChange(int $uid, int $type, string $uen)
    {
        $nowTime = time();
        // 获取用户的卡牌信息
        $wechatLingqianUserCardsModel = new WechatLingqianUserCards();
        $userCardList = $wechatLingqianUserCardsModel->getUserCardsInfo($uid);
        if ($type === 1)
        {   // 兑换 月运免费券
            $num = $userCardList[1]['num'] ?? 0;
            if ($num <= 0)
            {
                return [
                    'success' => false,
                    'msg' => '女王卡不足，兑换失败～',
                ];
            }
            $changeData[] = [
                'id' => $userCardList[1]['id'],
                'card_id' => 1,
                'num' => $userCardList[1]['num'] - 1,
                'change_num' => -1,
            ];
            // 月运 免费券 优惠券ID
            $cid = 770;
        } else
        {   // 兑换 年运免费券
            $cardConfig = Config::load(APP_PATH . 'webactive/extra/lingqian.php', 'lingqian', 'webactive');
            $changeData = [];
            foreach ($cardConfig['card_list'] as $cardId => $cardItem)
            {
                $num = $userCardList[$cardId]['num'] ?? 0;

                if ($num <= 0)
                {
                    return [
                        'success' => false,
                        'msg' => '卡牌还未集齐，兑换失败～',
                    ];
                }

                $changeData[] = [
                    'id' => $userCardList[$cardId]['id'],
                    'card_id' => $cardId,
                    'num' => 0, // 兑换 优惠券  卡牌 清零
                    'change_num' => -1 * $userCardList[$cardId]['num'],
                ];
            }
            // 年运 免费券 优惠券ID
            $cid = 771;
        }
        // 获取 准了号 对应的准了用户uid
        $zhunleUid = (new User())->getUidByUen($uen);
        // 扣除 卡牌
        $res = $wechatLingqianUserCardsModel->userChangeCardsInfo($uid, $changeData, $type);
        if ($res)
        {   // 发放 优惠券
            $userCouponModel = new UserCoupon();
            $couponInfo = (new ZlCouponAttr())->getInfoById($cid, ['desc', 'type', 'rand_min', 'rand_max', 'ur_id', 'gids']);
            $cData = [
                'uid' => $zhunleUid,
                'c_id' => $cid,
                'ur_id' => $couponInfo['ur_id'],
                'start_time' => $nowTime,
                'end_time' => strtotime("+7 day"),
                'give_time' => $nowTime,
                'status' => 0,
                'price' => $couponInfo['type'] == 4 ? mt_rand($couponInfo['rand_min'], $couponInfo['rand_max']) : 0,
                'is_give' => 0,
                'create_time' => $nowTime,
                'update_time' => 0,
            ];
            $ucId = $userCouponModel->insertGetId($cData);
            $ids[$ucId] = $ucId; // 添加未用于ID
            // 未使用
            $userCouponModel->listDataAdd($zhunleUid, $ids, 1);
            // 添加 兑换记录
            (new WechatLingqianChangeCouponRecord())->insert([
                'uid' => $uid,
                'type' => $type,
                'uen' => $uen,
                'zhunle_uid' => $zhunleUid,
                'create_time' => $nowTime,
            ]);

            return [
                'success' => true,
            ];
        } else
        {
            return [
                'success' => false,
                'msg' => '服务异常，请稍后再试～',
            ];
        }
    }
}